﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Framework.Comum.Pesquisa;
using NaviCar.Servico.Entidades;
using System.Web.Helpers;
using System.Data;
using NaviCar.DB.Repositorio;
using System.Collections.Specialized;
using System.IO;
using System.Text;
using Framework.Comum.DAL;
using Framework.Comum.Repositorio;
using System.Web.Script.Serialization;
using Framework.Comum.Tools;
using Newtonsoft.Json;
using Framework.Comum.DAL;

namespace NaviCar.Controllers
{
    [SessionState(System.Web.SessionState.SessionStateBehavior.Required)]
    public class BaseController<TEntity> : BaseController where TEntity : class, IClasseDados, new()
    {
        public string ControllerEditar { get; set; }
        public string ActionEditar { get; set; }

        public BaseController()
        {

        }

        public ActionResult Lista()
        {
            ServicoBase<TEntity> servico = new ServicoBase<TEntity>();

            IEnumerable<TEntity> lista = servico.RecuperarTodos();

            ViewBag.QuantidadeTotal = servico.RecuperarTodos().Count();
            ViewBag.PaginaAtual = 0;

            this.ViewBag.Lista = lista;

            return View();
        }

        public ActionResult Excluir(int id)
         {

             try
             {
                 ServicoBase<TEntity> servico = new ServicoBase<TEntity>();

                 servico.Excluir(id);

                 servico.Salvar();

                 return Content("Registro excluído com sucesso.");              

             }
             catch (Exception ex)
             {
                 return Content("Erro ao excluir registro.");
             }

         }

        public virtual ActionResult Novo()
        {
            return View();
        }


        

        public ActionResult Selecionar(int id)
        {
            try
            {
                
                ServicoBase<TEntity> servico = new ServicoBase<TEntity>();

                TEntity entidade = servico.RecuperarPorID(id);
                
                servico.Detach(entidade);

                TEntity copia = entidade.Copiar<TEntity>(entidade);

                //Serializador sr = new Serializador();
                string retorno = null;//sr.JsonSerialize(entidade);

                //var serializer = new JavaScriptSerializer();

                //serializer.RegisterConverters(new JavaScriptConverter[] { new EFObjectConverter() });

                //string included = JsonConvert. SerializeObject(entidade, Formatting.None, new JsonSerializerSettings { });


                //retorno = serializer.Serialize(entidade);

                return Json(new { sucesso = true, entidade = copia });
            }
            catch (Exception ex)
            {
                return Json(new { sucess = false, msg = string.Empty }, JsonRequestBehavior.AllowGet);
            }

        }

        [HttpPost]
        public virtual ActionResult Novo(TEntity entidade)
        {
            try
            {
              
                IClasseDados iclsDados = (IClasseDados)entidade;

                var chaves = (from f in iclsDados.ValoresChave where f == null select f).Count();

           
                foreach (string item in iclsDados.NomeChave)
                {
                    this.ModelState.Remove(item);
                }

                if (ModelState.IsValid)
                {
                    ServicoBase<TEntity> servico = new ServicoBase<TEntity>();

                    servico.Incluir(entidade);


                    if (!string.IsNullOrEmpty(this.ControllerEditar) && !string.IsNullOrEmpty(this.ActionEditar))
                    {
                        return RedirectToAction(this.ActionEditar, this.ControllerEditar);
                    }
                    else if (!string.IsNullOrEmpty(this.ActionEditar))
                    {
                        return RedirectToAction(this.ActionEditar);
                    }
                    else
                    {
                        return RedirectToAction("Lista");
                    }
                }

            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", "Erro ao Atualizar os dados.");
            }

            return View();
        }

        [HttpGet]
        public virtual ActionResult Editar(int? id )
         {
             try
             {
                 if (id.HasValue)
                 {
                     ServicoBase<TEntity> servico = new ServicoBase<TEntity>();

                     TEntity entidade = servico.RecuperarPorID(id);

                     return View(entidade);
                 }

                 return View();

             }
             catch (Exception ex)
             {
                 ModelState.AddModelError("", "Erro ao Atualizar os dados.");
             }

             return View("Novo");
        }

        [HttpPost]
        public virtual ActionResult Editar(TEntity entidade)
        {
            try
            {
              
                IClasseDados iclsDados = (IClasseDados)entidade;


                if (ModelState.IsValid)
                {
                    ServicoBase<TEntity> servico = new ServicoBase<TEntity>();


                    servico.Alterar(entidade);            

                    if (!string.IsNullOrEmpty(this.ControllerEditar) && !string.IsNullOrEmpty(this.ActionEditar))
                    {
                        return RedirectToAction(this.ActionEditar, this.ControllerEditar);
                    }
                    else if (!string.IsNullOrEmpty(this.ActionEditar))
                    {
                        return RedirectToAction(this.ActionEditar);
                    }
                    else
                    {
                        return RedirectToAction("Lista");
                    }
                }

            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", "Erro ao Atualizar os dados.");
            }

            return View();
        }

        //[HttpPost]
        //public ActionResult Editar(TEntity entidade)
        //{
            
        //    try
        //    {
        //        bool alterar = true;

        //        IClasseDados iclsDados = (IClasseDados)entidade;

        //        var chaves = (from f in iclsDados.ValoresChave where f == null select f).Count();

        //        if (chaves > 0) { alterar = false; }

        //        foreach (string item in iclsDados.NomeChave)
        //        {
        //            this.ModelState.Remove(item);
        //        }
                
        //        if (ModelState.IsValid)
        //        {
        //            ServicoBase<TEntity> servico = new ServicoBase<TEntity>();

        //            if (alterar)
        //            {
        //                servico.Alterar(entidade); 
        //            }
        //            else
        //            {
        //                servico.Incluir(entidade);
        //            }

        //            if (!string.IsNullOrEmpty(this.ControllerEditar) && !string.IsNullOrEmpty(this.ActionEditar))
        //            {
        //                return RedirectToAction(this.ActionEditar,this.ControllerEditar);
        //            }
        //            else if (!string.IsNullOrEmpty(this.ActionEditar))
        //            {
        //                return RedirectToAction(this.ActionEditar);
        //            }
        //            else
        //            {
        //                return RedirectToAction("Lista");
        //            }
        //        }

        //    }
        //    catch (Exception ex)
        //    {
        //        ModelState.AddModelError("", "Erro ao Atualizar os dados.");
        //    }

        //    return View();
        //}

        [HttpPost]
        public ActionResult Pesquisa()
        {
            NameValueCollection form = this.Request.Form;

            int quantidadeTotal = 0;
            int paginaAtual = 0;

            string ordem = this.Request.QueryString["ordGr"];

            List<TEntity> lista = this.OnBeforeExecutarPesquisa(form, ordem, out quantidadeTotal,out paginaAtual).ToList();
            ViewBag.QuantidadeTotal = quantidadeTotal;
            ViewBag.PaginaAtual = paginaAtual;

            return PartialView("ListaParcial",lista);
        }

        protected IQueryable<TEntity> OnBeforeExecutarPesquisa(NameValueCollection form, string ordenar, out int quantidadeTotal, out int paginaAtual)
        {
            var parametros = from p in form.AllKeys
                             where p.StartsWith("p_hd")
                             select p;

            List<CampoPesquisa> campos = new List<CampoPesquisa>();

            string nomeControlePesquisa = null;
            string[] valoresAuxiliares = null;
            int valorHiddenPesquisa = 0;
            //string ordenar = string.Empty;

            if (form.AllKeys.Contains("hdpgl") && !string.IsNullOrEmpty(form["hdpgl"])) valorHiddenPesquisa = int.Parse(form["hdpgl"]);
            //if (form.AllKeys.Contains("hdordl")) ordenar = form["hdordl"];

            paginaAtual = valorHiddenPesquisa;

            foreach (string item in parametros)
            {
                
                List<string> valores = new List<string>();

                nomeControlePesquisa = item.Replace("p_hd", "");

                if (!string.IsNullOrEmpty(form[nomeControlePesquisa]))
                {
                    valoresAuxiliares = form[item].Split('|');
                    CampoPesquisa campo = new CampoPesquisa();
                    campo.TipoPesquisa = (TipoPesquisa)Enum.Parse(typeof(TipoPesquisa), valoresAuxiliares[0]);
                    campo.Campo = valoresAuxiliares[1];
                    campo.Campo2 = valoresAuxiliares[2];

                    valores.Add(form[campo.Campo]);


                    if (!string.IsNullOrEmpty(campo.Campo2) && string.IsNullOrEmpty(form[campo.Campo2]))
                    {
                        valores.Add(form[campo.Campo2]);
                    }

                    campo.Valores = valores;

                    campos.Add(campo);
                                    
                }


            }

            return OnExecutarPesquisa(campos, form, valorHiddenPesquisa, ordenar, out quantidadeTotal);
        }

        protected IQueryable<TEntity> OnExecutarPesquisa(List<CampoPesquisa> campos, NameValueCollection form, int pagina, string ordenar, out int quantidadeTotal)
        {
            ServicoBase<TEntity> servico = new ServicoBase<TEntity>();

            return servico.Recuperar(campos, ordenar, pagina, 10, out quantidadeTotal);
        }


        
    }
}
